from fastapi import FastAPI, HTTPException, status, Depends, Request, Form, UploadFile, File
from fastapi.responses import HTMLResponse, RedirectResponse
from fastapi.templating import Jinja2Templates
from pydantic import BaseModel
from starlette.middleware.sessions import SessionMiddleware


from fastapi.staticfiles import StaticFiles  # 新增：用于挂载图片静态目录
from PIL import Image  # 新增：用于生成缩略图

from pathlib import Path

# -------------------------- 新增：图片上传配置 --------------------------
MAX_UPLOAD_IMAGES = 3  # 后台控制：单条评论最大上传图片数量（可自定义）
MAX_IMAGE_SIZE = 5 * 1024 * 1024  # 单张图片最大5MB（防止过大文件）
ALLOWED_IMAGE_TYPES = ["image/jpeg", "image/png", "image/gif"]  # 允许的图片格式
BASE_DIR = Path(__file__).resolve().parent
UPLOAD_DIR = Path(BASE_DIR) / "uploads"  # 图片总目录
ORIGINAL_DIR = UPLOAD_DIR / "original"   # 原图目录
THUMBNAIL_DIR = UPLOAD_DIR / "thumbnail" # 缩略图目录

# 确保目录存在（不存在则自动创建）
for dir_path in [UPLOAD_DIR, ORIGINAL_DIR, THUMBNAIL_DIR]:
    if not dir_path.exists():
        dir_path.mkdir(parents=True, exist_ok=True)



from datetime import datetime, timedelta
from typing import List, Optional
import json
import os
import uuid
from auth import (
    User, UserCreate, UserLogin, get_user_by_username,
    verify_password, get_password_hash, load_users, save_users
)

# 初始化FastAPI应用
app = FastAPI(title="BBS 评论系统 with Session Auth")


# -------------------------- 挂载静态目录 --------------------------
# 前端通过 /uploads/xxx 访问图片（例如：/uploads/thumbnail/xxx.jpg）
app.mount("/uploads", StaticFiles(directory=UPLOAD_DIR), name="static_uploads")




# 配置模板
templates = Jinja2Templates(directory="templates")

# 添加Jinja2日期格式化过滤器（用于模板中的日期显示）
def datetimeformat(value, format="%Y-%m-%d %H:%M"):
    if isinstance(value, str):
        try:
            value = datetime.fromisoformat(value)
        except ValueError:
            return value  # 格式错误时返回原始值
    return value.strftime(format)

templates.env.filters['datetimeformat'] = datetimeformat

# 数据存储文件路径
BASE_DIR = os.path.dirname(os.path.abspath(__file__))

# 修改数据文件路径定义（替换原来的DATA_FILE和SESSIONS_FILE）
DATA_FILE = os.path.join(BASE_DIR, "bbs_data.json")
SESSIONS_FILE = os.path.join(BASE_DIR, "sessions.json")

# 会话密钥配置
SECRET_KEY = os.getenv("BBS_SECRET_KEY", "dev-secret-key-1234567890abcdef")
app.add_middleware(SessionMiddleware, secret_key=SECRET_KEY, session_cookie="bbs_session")


# 评论数据模型
class Comment(BaseModel):
    id: Optional[int] = None
    content: str
    author: str
    author_id: int
    parent_id: Optional[int] = None
    created_at: Optional[datetime] = None
     # -------------------------- 新增：图片相关字段 --------------------------
    image_urls: Optional[List[str]] = None  # 高清原图URL列表（例如：["/uploads/original/xxx.jpg"]）
    thumbnail_urls: Optional[List[str]] = None  # 缩略图URL列表（例如：["/uploads/thumbnail/xxx.jpg"]）

# 新增：仅接收前端提交的字段（content + parent_id）
class CommentCreate(BaseModel):
    content: str
    parent_id: Optional[int] = None  # 可选，回复时才传

# 会话文件处理（带容错）
def init_sessions_file():
    if not os.path.exists(SESSIONS_FILE):
        with open(SESSIONS_FILE, 'w', encoding='utf-8') as f:
            json.dump({}, f, ensure_ascii=False)
    else:
        try:
            with open(SESSIONS_FILE, 'r', encoding='utf-8') as f:
                json.load(f)
        except json.JSONDecodeError:
            with open(SESSIONS_FILE, 'w', encoding='utf-8') as f:
                json.dump({}, f, ensure_ascii=False)


def save_session(session_id: str, user_id: int):
    init_sessions_file()  # 初始化会话文件（sessions.json）
    with open(SESSIONS_FILE, 'r+', encoding='utf-8') as f:
        try:
            sessions = json.load(f)  # 读取已有的会话数据
        except json.JSONDecodeError:
            sessions = {}
        

        # !!!记录会话过期时间：当前时间 + 24小时
        sessions[session_id] = {
            "user_id": user_id,  # 关联的用户ID
            "expires_at": (datetime.now() + timedelta(days=1)).isoformat()
        }
        
        # 写入更新后的会话数据
        f.seek(0)
        f.truncate()
        json.dump(sessions, f, ensure_ascii=False, default=str)


def get_user_from_session(session_id: str) -> Optional[User]:
    init_sessions_file()
    with open(SESSIONS_FILE, 'r', encoding='utf-8') as f:
        try:
            sessions = json.load(f)
        except json.JSONDecodeError:
            sessions = {}
        
        if session_id in sessions:
            session_data = sessions[session_id]
            try:
                # !!!! 校验会话是否过期：解析过期时间并与当前时间对比
                expires_at = datetime.fromisoformat(session_data["expires_at"])
                if expires_at > datetime.now():
                    # 未过期：返回关联的用户信息
                    users = load_users()
                    return next((u for u in users if u.id == session_data["user_id"]), None)
                else:
                    # 已过期：删除无效会话，避免冗余数据
                    del sessions[session_id]
                    with open(SESSIONS_FILE, 'w', encoding='utf-8') as f_update:
                        json.dump(sessions, f_update, ensure_ascii=False, default=str)
            except (ValueError, KeyError):
                return None
    return None


# 获取当前登录用户
def get_current_user(request: Request) -> Optional[User]:
    session_id = request.cookies.get("session_id")
    if session_id:
        return get_user_from_session(session_id)
    return None


# 评论数据处理（带容错）
def init_data_file():
    if not os.path.exists(DATA_FILE):
        with open(DATA_FILE, 'w', encoding='utf-8') as f:
            json.dump([], f, ensure_ascii=False)
    else:
        try:
            with open(DATA_FILE, 'r', encoding='utf-8') as f:
                json.load(f)
        except json.JSONDecodeError:
            with open(DATA_FILE, 'w', encoding='utf-8') as f:
                json.dump([], f, ensure_ascii=False)


def load_comments() -> List[Comment]:
    init_data_file()
    with open(DATA_FILE, 'r', encoding='utf-8') as f:
        try:
            comments_data = json.load(f)
            return [Comment(**item) for item in comments_data]
        except (json.JSONDecodeError, TypeError):
            return []


def save_comments(comments: List[Comment]):
    with open(DATA_FILE, 'w', encoding='utf-8') as f:
        comments_dict = [comment.dict() for comment in comments]
        json.dump(comments_dict, f, ensure_ascii=False, default=str)


# 页面路由
@app.get("/register", response_class=HTMLResponse)
def register_page(request: Request, current_user: Optional[User] = Depends(get_current_user)):
    if current_user:
        return RedirectResponse(url="/", status_code=303)
    return templates.TemplateResponse("register.html", {"request": request})


@app.post("/register", response_class=HTMLResponse)
def handle_register(
        request: Request,
        username: str = Form(...),
        password: str = Form(...)
):
    if get_user_by_username(username):
        return templates.TemplateResponse("register.html", {
            "request": request,
            "error": "用户名已存在，请更换其他用户名"
        })

    users = load_users()
    new_user_id = max([u.id for u in users], default=0) + 1
    hashed_password = get_password_hash(password)

    new_user = User(
        id=new_user_id,
        username=username,
        password=hashed_password,
        created_at=datetime.now()
    )

    users.append(new_user)
    save_users(users)
    return RedirectResponse(url="/login?registered=true", status_code=303)


@app.get("/login", response_class=HTMLResponse)
def login_page(
        request: Request,
        registered: Optional[bool] = False,
        current_user: Optional[User] = Depends(get_current_user)
):
    if current_user:
        return RedirectResponse(url="/", status_code=303)
    return templates.TemplateResponse("login.html", {
        "request": request,
        "registered": registered
    })


@app.post("/login", response_class=HTMLResponse)
def handle_login(
        request: Request,
        username: str = Form(...),
        password: str = Form(...)
):
    # ... 用户名密码验证逻辑 ...
    user = get_user_by_username(username)
    if not user or not verify_password(password, user.password):
        return templates.TemplateResponse("login.html", {
            "request": request,
            "error": "用户名或密码错误，请重新输入"
        })

     # 生成唯一会话ID
    session_id = str(uuid.uuid4())
    # 保存会话（关联用户ID和过期时间）
    save_session(session_id, user.id)


    # 设置Cookie，关键参数控制时效
    response = RedirectResponse(url="/", status_code=303)
    response.set_cookie(
        key="session_id",  # 会话标识Cookie的key
        value=session_id,  # 会话ID值
        httponly=True,     # 防止JS读取，提升安全性
        max_age=86400,     # !!!登录时效核心：Cookie有效期=24小时（86400秒）
        secure=False,      # 开发环境关闭HTTPS校验（生产环境需设为True）
        samesite="lax"     # 限制跨站请求，提升安全性
    )
    return response


@app.get("/logout", response_class=HTMLResponse)
def handle_logout(request: Request):
    response = RedirectResponse(url="/", status_code=303)
    response.delete_cookie(key="session_id")
    return response


@app.get("/", response_class=HTMLResponse)
def home_page(request: Request, current_user: Optional[User] = Depends(get_current_user)):
    comments = load_comments()
    return templates.TemplateResponse("index.html", {
        "request": request,
        "comments": comments,
        "current_user": current_user,
        "MAX_UPLOAD_IMAGES": MAX_UPLOAD_IMAGES  # 新增：传递最大上传数量到前端
    })


# API路由
@app.get("/comments", response_model=List[Comment])
def api_get_comments():
    return load_comments()


# @app.post("/comments", response_model=Comment, status_code=status.HTTP_201_CREATED)
# def api_create_comment(
#         comment: CommentCreate,

#         # 注意：文件上传需用 File(...)，且参数顺序需放在最后
#         content: str = Form(...),  # 评论文字内容
#         parent_id: Optional[int] = Form(None),  # 父评论ID（回复用）
#         images: List[UploadFile] = File(default=None),  # 上传的图片列表（可选）

#         current_user: Optional[User] = Depends(get_current_user)
# ):
#     # 1. 基础校验（登录状态+文字内容）
#     if not current_user:
#         raise HTTPException(status_code=401, detail="请先登录再发表评论")
#     if not content.strip():
#         raise HTTPException(status_code=400, detail="评论内容不能为空")
    
#     comments = load_comments()
#     new_comment_id = max([c.id for c in comments], default=0) + 1

#  # 用 Comment 模型构造响应数据（后端填充 author/author_id/created_at）
#     new_comment = Comment(
#         id=new_comment_id,
#         content=comment.content,  # 来自前端提交
#         author=current_user.username,  # 后端从登录状态获取
#         author_id=current_user.id,  # 后端从登录状态获取
#         parent_id=comment.parent_id,  # 来自前端提交（可选）
#         created_at=datetime.now()  # 后端生成时间
#     )

#     comments.append(new_comment)
#     save_comments(comments)
    
#     # 添加调试日志
#     print(f"保存新评论: {new_comment.dict()}")
#     print(f"评论总数: {len(comments)}")
    
#     return new_comment

# -------------------------- 改造：支持图片上传的评论创建接口 --------------------------
@app.post("/comments", response_model=Comment, status_code=status.HTTP_201_CREATED)
async def api_create_comment(
        # 注意：文件上传需用 File(...)，且参数顺序需放在最后
        content: str = Form(...),  # 评论文字内容
        parent_id: Optional[int] = Form(None),  # 父评论ID（回复用）
        images: List[UploadFile] = File(default=None),  # 上传的图片列表（可选）
        current_user: Optional[User] = Depends(get_current_user)
):
    # 1. 基础校验（登录状态+文字内容）
    if not current_user:
        raise HTTPException(status_code=401, detail="请先登录再发表评论")
    if not content.strip():
        raise HTTPException(status_code=400, detail="评论内容不能为空")

    # 2. 图片数量控制（后台配置生效）
    if images and len(images) > MAX_UPLOAD_IMAGES:
        raise HTTPException(
            status_code=400, 
            detail=f"单条评论最多上传{MAX_UPLOAD_IMAGES}张图片"
        )

    # 3. 处理图片（生成原图+缩略图+返回URL）
    image_urls = []  # 最终存储的原图URL列表
    thumbnail_urls = []  # 最终存储的缩略图URL列表

    if images:
        for img_file in images:
            # 3.1 校验图片格式和大小
            if img_file.content_type not in ALLOWED_IMAGE_TYPES:
                raise HTTPException(
                    status_code=400, 
                    detail=f"不支持的图片格式，仅允许{[t.split('/')[1] for t in ALLOWED_IMAGE_TYPES]}格式"
                )
            if img_file.size > MAX_IMAGE_SIZE:
                raise HTTPException(
                    status_code=400, 
                    detail=f"单张图片最大不能超过{MAX_IMAGE_SIZE//1024//1024}MB"
                )

            # 3.2 生成唯一文件名（避免重复覆盖）
            file_ext = img_file.filename.split(".")[-1].lower()  # 取文件后缀（jpg/png）
            unique_filename = f"{uuid.uuid4()}.{file_ext}"  # 用UUID生成唯一名

            # 3.3 保存原图到 original 目录
            original_file_path = ORIGINAL_DIR / unique_filename
            with open(original_file_path, "wb") as f:
                f.write(await img_file.read())  # 异步读取文件内容并保存

            # 3.4 生成缩略图（固定宽高：300x300，保持原图比例，不拉伸）
            thumbnail_size = (300, 300)  # 缩略图尺寸（可自定义）
            with Image.open(original_file_path) as img:
                img.thumbnail(thumbnail_size)  # 按比例缩小（不会变形）
                thumbnail_file_path = THUMBNAIL_DIR / unique_filename
                img.save(thumbnail_file_path)  # 保存缩略图

            # 3.5 拼接图片URL（前端可直接访问）
            original_url = f"/uploads/original/{unique_filename}"
            thumbnail_url = f"/uploads/thumbnail/{unique_filename}"
            image_urls.append(original_url)
            thumbnail_urls.append(thumbnail_url)

    # 4. 保存评论数据（含图片URL）
    comments = load_comments()
    new_comment_id = max([c.id for c in comments], default=0) + 1
    new_comment = Comment(
        id=new_comment_id,
        content=content,
        author=current_user.username,
        author_id=current_user.id,
        parent_id=parent_id,
        created_at=datetime.now(),
        image_urls=image_urls if image_urls else None,  # 存入原图URL
        thumbnail_urls=thumbnail_urls if thumbnail_urls else None  # 存入缩略图URL
    )
    comments.append(new_comment)
    save_comments(comments)

    return new_comment




# @app.put("/comments/{comment_id}", response_model=Comment)
# async def api_update_comment(
#         comment_id: int,
#         # updated_data: dict,  # 使用字典接收数据

#         content: str = Form(..., description="评论内容，不能为空"),  # 评论文字内容
#         # deleted_images: List[str] = Form(default=[]),  # 要删除的图片URL列表
#         # deleted_images: List[str] = Form(default_factory=list),  # 关键修改
#         deleted_images: List[str] = Form(default_factory=list, description="要删除的图片URL列表"),

#         # images: List[UploadFile] = File(default=None),  # 新上传的图片
#         # images: Optional[List[UploadFile]] = File(default=None),  # 允许为None
#         images: Optional[List[UploadFile]] = File(default=None, description="新上传的图片列表"),

#         current_user: Optional[User] = Depends(get_current_user)
# ):
#     if not current_user:
#         raise HTTPException(status_code=401, detail="请先登录再修改评论")
    
#     # 1. 验证内容不为空
#     if not content.strip():
#         raise HTTPException(
#             status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
#             detail="评论内容不能为空"
#         )
    
#     # 2. 验证deleted_images是列表（兜底）
#     if not isinstance(deleted_images, list):
#         raise HTTPException(
#             status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
#             detail="删除的图片列表格式错误"
#         )
    

#     comments = load_comments()
    
#     for idx, comment in enumerate(comments):
#         if comment.id == comment_id:
#             # 检查是否为顶级评论
#             if comment.parent_id is not None:
#                 raise HTTPException(status_code=403, detail="只能修改顶级评论")
                
#             # 检查是否为作者
#             if comment.author_id != current_user.id:
#                 raise HTTPException(status_code=403, detail="没有权限修改他人的评论")

#             # 严格只更新content字段，完全排除author相关字段
#             if "content" in updated_data and updated_data["content"].strip():
#                 updated_comment = comment.dict()  # 复制原有评论数据
#                 updated_comment["content"] = updated_data["content"].strip()  # 仅更新内容
                
#                  # 添加更新评论时间的逻辑
#                 updated_comment["created_at"] = datetime.now() 
                
#                 comments[idx] = Comment(** updated_comment)
#                 save_comments(comments)
#                 return comments[idx]
#             else:
#                 raise HTTPException(status_code=400, detail="必须提供有效的评论内容")
            
            
#             # 处理图片删除
#             updated_image_urls = []
#             updated_thumbnail_urls = []

#             if comment.image_urls and comment.thumbnail_urls:
#                 # 保留未被删除的图片
#                 for img_url, thumb_url in zip(comment.image_urls, comment.thumbnail_urls):
#                     if img_url not in deleted_images:
#                         updated_image_urls.append(img_url)
#                         updated_thumbnail_urls.append(thumb_url)
#                     else:
#                         # 从服务器删除图片文件
#                         img_filename = img_url.split("/")[-1]
#                         original_file = ORIGINAL_DIR / img_filename
#                         thumbnail_file = THUMBNAIL_DIR / img_filename
#                         if original_file.exists():
#                             os.remove(original_file)
#                         if thumbnail_file.exists():
#                             os.remove(thumbnail_file)
            
#             # 处理新上传的图片
#             if images:
#                 # 检查总图片数量是否超过限制
#                 if len(updated_image_urls) + len(images) > MAX_UPLOAD_IMAGES:
#                     raise HTTPException(
#                         status_code=400, 
#                         detail=f"评论最多只能包含{MAX_UPLOAD_IMAGES}张图片"
#                     )
                
#                 for img_file in images:
#                     # 校验图片格式和大小
#                     if img_file.content_type not in ALLOWED_IMAGE_TYPES:
#                         raise HTTPException(
#                             status_code=400, 
#                             detail=f"不支持的图片格式，仅允许{[t.split('/')[1] for t in ALLOWED_IMAGE_TYPES]}格式"
#                         )
#                     if img_file.size > MAX_IMAGE_SIZE:
#                         raise HTTPException(
#                             status_code=400, 
#                             detail=f"单张图片最大不能超过{MAX_IMAGE_SIZE//1024//1024}MB"
#                         )

#                     # 生成唯一文件名
#                     file_ext = img_file.filename.split(".")[-1].lower()
#                     unique_filename = f"{uuid.uuid4()}.{file_ext}"

#                     # 保存原图
#                     original_file_path = ORIGINAL_DIR / unique_filename
#                     with open(original_file_path, "wb") as f:
#                         f.write(await img_file.read())

#                     # 生成缩略图
#                     thumbnail_size = (300, 300)
#                     with Image.open(original_file_path) as img:
#                         img.thumbnail(thumbnail_size)
#                         thumbnail_file_path = THUMBNAIL_DIR / unique_filename
#                         img.save(thumbnail_file_path)

#                     # 添加到URL列表
#                     original_url = f"/uploads/original/{unique_filename}"
#                     thumbnail_url = f"/uploads/thumbnail/{unique_filename}"
#                     updated_image_urls.append(original_url)
#                     updated_thumbnail_urls.append(thumbnail_url)
            
#              # 更新评论数据
#             updated_comment = comment.dict()
#             updated_comment["content"] = content.strip()
#             updated_comment["created_at"] = datetime.now()
#             updated_comment["image_urls"] = updated_image_urls if updated_image_urls else None
#             updated_comment["thumbnail_urls"] = updated_thumbnail_urls if updated_thumbnail_urls else None
            
#             comments[idx] = Comment(** updated_comment)
#             save_comments(comments)
#             return comments[idx]


            
            
#     raise HTTPException(status_code=404, detail="要修改的评论不存在")

@app.put("/comments/{comment_id}", response_model=Comment)
async def api_update_comment(
        comment_id: int,
        content: str = Form(..., description="评论内容，不能为空"),
        deleted_images: List[str] = Form(default_factory=list, description="要删除的图片URL列表"),
        images: Optional[List[UploadFile]] = File(default=None, description="新上传的图片列表"),
        current_user: Optional[User] = Depends(get_current_user)
):
    # 1. 验证登录状态
    if not current_user:
        raise HTTPException(status_code=401, detail="请先登录再修改评论")
    
    # 2. 验证评论内容不为空
    if not content.strip():
        raise HTTPException(
            status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
            detail="评论内容不能为空"
        )
    
    # 3. 验证删除图片列表格式（兜底）
    if not isinstance(deleted_images, list):
        raise HTTPException(
            status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
            detail="删除的图片列表格式错误"
        )
    
    # 4. 加载评论并查找目标评论
    comments = load_comments()
    target_index = None
    target_comment = None
    for idx, comment in enumerate(comments):
        if comment.id == comment_id:
            target_index = idx
            target_comment = comment
            break
    
    # 5. 验证评论是否存在
    if target_comment is None:
        raise HTTPException(status_code=404, detail="要修改的评论不存在")
    
    # 6. 验证权限（只能修改顶级评论和自己的评论）
    if target_comment.parent_id is not None:
        raise HTTPException(status_code=403, detail="只能修改顶级评论")
    if target_comment.author_id != current_user.id:
        raise HTTPException(status_code=403, detail="没有权限修改他人的评论")
    
    # 7. 处理图片删除
    updated_image_urls = []
    updated_thumbnail_urls = []
    # 保留未被删除的图片
    if target_comment.image_urls and target_comment.thumbnail_urls:
        for img_url, thumb_url in zip(target_comment.image_urls, target_comment.thumbnail_urls):
            if img_url not in deleted_images:
                updated_image_urls.append(img_url)
                updated_thumbnail_urls.append(thumb_url)
            else:
                # 从服务器删除图片文件
                img_filename = img_url.split("/")[-1]
                original_file = ORIGINAL_DIR / img_filename
                thumbnail_file = THUMBNAIL_DIR / img_filename
                if original_file.exists():
                    os.remove(original_file)
                if thumbnail_file.exists():
                    os.remove(thumbnail_file)
    
    # 8. 处理新上传的图片
    if images:
        # 检查总图片数量是否超过限制
        if len(updated_image_urls) + len(images) > MAX_UPLOAD_IMAGES:
            raise HTTPException(
                status_code=400,
                detail=f"评论最多只能包含{MAX_UPLOAD_IMAGES}张图片"
            )
        
        for img_file in images:
            # 验证图片格式
            if img_file.content_type not in ALLOWED_IMAGE_TYPES:
                raise HTTPException(
                    status_code=400,
                    detail=f"不支持的图片格式，仅允许{[t.split('/')[1] for t in ALLOWED_IMAGE_TYPES]}格式"
                )
            # 验证图片大小
            if img_file.size > MAX_IMAGE_SIZE:
                raise HTTPException(
                    status_code=400,
                    detail=f"单张图片最大不能超过{MAX_IMAGE_SIZE//1024//1024}MB"
                )
            
            # 生成唯一文件名
            file_ext = img_file.filename.split(".")[-1].lower()
            unique_filename = f"{uuid.uuid4()}.{file_ext}"
            
            # 保存原图
            original_file_path = ORIGINAL_DIR / unique_filename
            with open(original_file_path, "wb") as f:
                f.write(await img_file.read())
            
            # 生成并保存缩略图
            thumbnail_size = (300, 300)
            with Image.open(original_file_path) as img:
                img.thumbnail(thumbnail_size)
                thumbnail_file_path = THUMBNAIL_DIR / unique_filename
                img.save(thumbnail_file_path)
            
            # 添加到URL列表
            original_url = f"/uploads/original/{unique_filename}"
            thumbnail_url = f"/uploads/thumbnail/{unique_filename}"
            updated_image_urls.append(original_url)
            updated_thumbnail_urls.append(thumbnail_url)
    
    # 9. 更新评论数据
    updated_comment = target_comment.dict()  # 复制原有评论数据
    updated_comment["content"] = content.strip()  # 更新评论内容
    updated_comment["created_at"] = datetime.now()  # 更新时间
    updated_comment["image_urls"] = updated_image_urls if updated_image_urls else None
    updated_comment["thumbnail_urls"] = updated_thumbnail_urls if updated_thumbnail_urls else None
    
    # 10. 保存并返回更新后的评论
    comments[target_index] = Comment(** updated_comment)
    save_comments(comments)
    return comments[target_index]


@app.delete("/comments/{comment_id}", status_code=status.HTTP_204_NO_CONTENT)
def api_delete_comment(
        comment_id: int,
        current_user: Optional[User] = Depends(get_current_user)
):
    if not current_user:
        raise HTTPException(status_code=401, detail="请先登录再删除评论")

    comments = load_comments()
    target_comment = next((c for c in comments if c.id == comment_id), None)
    if not target_comment:
        raise HTTPException(status_code=404, detail="要删除的评论不存在")

    if target_comment.author_id != current_user.id:
        raise HTTPException(status_code=403, detail="没有权限删除他人的评论")


     # -------------------------- 新增：删除评论关联的图片文件 --------------------------
    if target_comment.image_urls:
        for img_url in target_comment.image_urls:
            # 从URL中提取文件名（例如：/uploads/original/xxx.jpg → xxx.jpg）
            img_filename = img_url.split("/")[-1]
            # 删除原图和缩略图
            original_file = ORIGINAL_DIR / img_filename
            thumbnail_file = THUMBNAIL_DIR / img_filename
            if original_file.exists():
                os.remove(original_file)
            if thumbnail_file.exists():
                os.remove(thumbnail_file)



    # 过滤掉目标评论和它的回复            
    filtered_comments = [
        c for c in comments
        if c.id != comment_id and c.parent_id != comment_id
    ]

    save_comments(filtered_comments)
    return None


if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000, reload=True)